home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / viewers / prev / prev.lha / cone.c < prev    next >
C/C++ Source or Header  |  1991-03-10  |  4KB  |  220 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <vogle.h>
  4. #include "art.h"
  5. #include "macro.h"
  6. #include "gram.h"
  7.  
  8. extern int    lookatdone;
  9. extern int    longlines;
  10. extern mats    *mstackp;
  11. extern hlist    *fhlist;
  12. extern float    tolerance;
  13.  
  14. /*
  15.  * coneinit
  16.  *
  17.  *    initialise the function pointers and fields for a cone object,
  18.  * returning its pointer.
  19.  */
  20. void
  21. coneinit(o, d)
  22.     object    *o;
  23.     details *d;
  24. {
  25.     int        first, faces;
  26.     vector        base, tip, basescale, tipscale, tmp;
  27.     details        *ld;
  28.     float        grad;
  29.     float    apex_x, apex_y, apex_z, apex_r;
  30.     float    base_x, base_y, base_z, base_r;
  31.     float    len0, len1,  len_x, len_y, len_z;
  32.     float    cosine, sine, dx1, dy1, dx2, dy2, delta;
  33.     float    cx1, cy1, cx2, cy2;
  34.     int    i;
  35.     Matrix    m;
  36.  
  37.     if (!lookatdone)
  38.         deflookat();
  39.  
  40.     faces = 0;
  41.     first = 1;
  42.  
  43.     base.x = base.y = base.z = 0.0;
  44.     tip.x = tip.y = tip.z = 1.0;
  45.  
  46.     basescale.x = basescale.y = 1.0;
  47.     tipscale.x = tipscale.y = 0.0;
  48.  
  49.     while (d != (details *)NULL) {
  50.         switch (d->type) {
  51.         case VERTEX:
  52.             tip = d->u.v;
  53.             break;
  54.         case CENTER:
  55.             if (faces == 0)
  56.                 base = d->u.v;
  57.             else
  58.                 tip = d->u.v;
  59.             faces++;
  60.             break;
  61.         case RADIUS:
  62.             if (first) {
  63.                 basescale.x = basescale.y = d->u.f;
  64.                 first = 0;
  65.             } else
  66.                 tipscale.x = tipscale.y = d->u.f;
  67.             break;
  68.         case RADII:
  69.              if (first) {
  70.                 tipscale.x = d->u.v.x;
  71.                 tipscale.y = d->u.v.y;
  72.                 first = 0;
  73.             } else {
  74.                 basescale.x = d->u.v.x;
  75.                 basescale.y = d->u.v.y;
  76.             }
  77.             break;
  78.         default:
  79.             warning("art: illegal field in cone ignored.\n");
  80.         }
  81.         ld = d;
  82.         d = d->nxt;
  83.         free(ld);
  84.     }
  85.  
  86.             /* this axis is done in obj_transform */
  87.     basescale.z = tipscale.z = 1.0;
  88.  
  89.     if (faces == 2) {
  90.         if (tipscale.x > basescale.x) {
  91.             tmp = tip;
  92.             tip = base;
  93.             base = tmp;
  94.             tmp = tipscale;
  95.             tipscale = basescale;
  96.             basescale = tmp;
  97.         }
  98.         o->obj.cne_tipval = tipscale.x / basescale.x;
  99.         grad = (tip.x - base.x) / (basescale.x - tipscale.x);
  100.         tip.x += grad * tipscale.x;
  101.         grad = (tip.y - base.y) / (basescale.x - tipscale.x);
  102.         tip.y += grad * tipscale.x;
  103.         grad = (tip.z - base.z) / (basescale.x - tipscale.x);
  104.         tip.z += grad * tipscale.x;
  105.     } else 
  106.         o->obj.cne_tipval = 0.0;
  107.  
  108.     tmp.x = (tip.x + base.x) / 2.0;
  109.     tmp.y = (tip.y + base.y) / 2.0;
  110.     tmp.z = (tip.z + base.z) / 2.0;
  111.  
  112.     len_x = tip.x - base.x;
  113.     len_y = tip.y - base.y;
  114.     len_z = tip.z - base.z;
  115.  
  116.     len0 = sqrt(len_x * len_x + len_y * len_y + len_z * len_z);
  117.  
  118.     len1 = sqrt(len_x * len_x + len_z * len_z);
  119.  
  120.     /*
  121.      * Draw the axis center line in YELLOW
  122.      */
  123.     color(YELLOW);
  124.     move(tip.x, tip.y, tip.z);
  125.     draw(base.x, base.y, base.z);
  126.  
  127.     /*
  128.      * And the rest in GREEN...
  129.      */
  130.     color(GREEN);
  131.  
  132.     pushmatrix();
  133.  
  134.         calctransforms(mstackp);
  135.         multmatrix(mstackp->obj2ray);
  136.  
  137.         translate(base.x, base.y, base.z);
  138.  
  139.         identmatrix(m);
  140.  
  141.         if (len1 == 0.0) {
  142.             cosine = 0.0;
  143.             sine = 1.0;
  144.         } else {
  145.             cosine = len_z / len1;
  146.             sine = len_x / len1;
  147.         }
  148.  
  149.         /* rotate about y */
  150.         m[0][0] = cosine;
  151.         m[0][2] = -sine;
  152.         m[2][0] = sine;
  153.         m[2][2] = cosine;
  154.         multmatrix(m);
  155.  
  156.         identmatrix(m);
  157.  
  158.         if (len0 == 0.0) {
  159.             cosine = 0.0;
  160.             sine = 1.0;
  161.         } else {
  162.             cosine = len1 / len0;
  163.             sine = -len_y / len0;
  164.         }
  165.  
  166.         /* rotate about x */
  167.         m[1][1] = cosine;
  168.         m[1][2] = sine;
  169.         m[2][1] = -sine;
  170.         m[2][2] = cosine;
  171.         multmatrix(m);
  172.  
  173.         /*
  174.          * Draw the end circles...
  175.          */
  176.         pushmatrix();
  177.             scale(basescale.x, basescale.y, 1.0);
  178.  
  179.             circle (0.0, 0.0, 1.0);
  180.  
  181.             pushmatrix();
  182.                 scale(tipscale.x, tipscale.y, 1.0);
  183.                 translate(0.0, 0.0, len0);
  184.                 circle (0.0, 0.0, 1.0);
  185.             popmatrix();
  186.         popmatrix();
  187.  
  188.  
  189.  
  190.         /*
  191.          * Draw the logitudinal lines...
  192.          */
  193.         delta = 2 * PI / longlines;
  194.  
  195.         cosine = cos(delta);
  196.         sine = sin(delta);
  197.  
  198.         cx1 = basescale.x;
  199.         cy1 = 0.0;
  200.         cx2 = tipscale.x;
  201.         cy2 = 0.0;
  202.  
  203.         move(cx1, cy1, 0.0);
  204.         draw(cx2, cy2, len0);
  205.  
  206.         for (i = 0; i < longlines; i++) {
  207.             dx1 = cx1;
  208.             dy1 = cy1;
  209.             cx1 = dx1 * cosine - dy1 * sine;
  210.             cy1 = dx1 * sine + dy1 * cosine;
  211.             dx2 = cx2;
  212.             dy2 = cy2;
  213.             cx2 = dx2 * cosine - dy2 * sine;
  214.             cy2 = dx2 * sine + dy2 * cosine;
  215.             move(cx1, cy1, 0.0);
  216.             draw(cx2, cy2, len0);
  217.         }
  218.     popmatrix();
  219. }
  220.